home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacWorld Secrets (4th Edition)
/
Mac Secrets CD 4th Ed.toast
/
Shareware & Freeware
/
KeyQuencer 1.2.2
/
Developer’s toolkit
/
Common code
/
A4Globals.h
next >
Wrap
C/C++ Source or Header
|
1995-12-16
|
8KB
|
209 lines
// =============================================================================
// COMPILER-INDEPENDENT GLOBAL STORAGE
// ©1994-96 Alessandro Levi Montalcini <alm@torino.alpcom.it>
// The latest version is available on ftp://ftp.alpcom.it/software/mac/LMontalcini
// This text looks best in monaco 9 font, 4 spaces per tab, no wrapping
// WARNING: THIS HEADER SHOULD ONLY BE INCLUDED ONCE THROUGHOUT THE PROJECT
// Unaltered copies of this file may be freely distributed; you may use this
// code in your projects without asking my permission and modify it for your
// personal use, but you should not distribute any modified versions. Send
// me your additions if you want them to be included in the next version.
// If you use this header in your projects, I'd be happy to get some credits
// or to receive a copy of the program. However, this is absolutely not
// required if you can't do it for any reason.
//==============================================================================
// Original code and comments are copyright ©Alessandro Levi Montalcini (ALM)
// ALM 11/23/94: released as part of the KeyQuencer developer's toolkit
// ALM 04/01/95: changed defined(powerc) to GENERATINGPOWERPC
// ALM 05/18/95: merged ALM and RMT macros, added comments and sample code
// Additions to A4Globals.h by Robert M. Thorne of Aladdin Systems, Inc. (RMT)
// RMT Add code to make this conditional if A4 based.
// RMT 4/20/95: fixed macro for MWerks (was redefining GLOBALS_ALWAYS_AVAILABLE)
//==============================================================================
#ifndef _H_a4globals
#define _H_a4globals
//==============================================================================
// Check if the current project needs to set up the environment before accessing
// its global variables. Globals are always available in PowerPC code fragments
// and in 68K applications, whereas 68K A4-based projects have to set up the A4
// register before using the globals and restore it when they are done.
// Note: this method can't be used to gain access to 68K A5-based application
// globals from callback routines such as VBL or Time Manager tasks.
// (this section was originally conceived by RMT)
#if GENERATINGPOWERPC // any PowerPC compiler
#define GLOBALS_ALWAYS_AVAILABLE 1
#elif defined(THINK_C) // Think C 68K
#if __option(a4_globals)
#define GLOBALS_ALWAYS_AVAILABLE 0
#else
#define GLOBALS_ALWAYS_AVAILABLE 1
#endif
#elif defined(__MWERKS__) // CodeWarrior 68K
#if __A5__
#define GLOBALS_ALWAYS_AVAILABLE 1
#else
#define GLOBALS_ALWAYS_AVAILABLE 0
#endif
#else // unknown compiler, stop here
#error unsupported compiler
#endif // end of project type check
//==============================================================================
// The following macros can be used by any project to set up and restore the
// globals environment. Both the Think C and CodeWarrior headers include static
// code, so this header should only be included once throughout the project.
//
// The #include "A4Globals.h" statement should be at the beginning of the source
// file containing the main routine; you should declare a "world" local variable
// of type "long" and call MAIN_SETUP_GLOBALS(world) at the beginning of the
// main routine and MAIN_RESTORE_GLOBALS(world) at the end. Remember not to use
// any "return" statement between the two macros, or you'll return to the caller
// without restoring the A4 register (which can be really bad). Also, don't try
// to use global variables after the MAIN_RESTORE_GLOBALS macro; if you need a
// global for your function result, copy it to a local variable. You can use the
// TEMP_SETUP_GLOBALS and TEMP_RESTORE_GLOBALS macros in routines that are
// called without going through the main entry point, as long as they are in
// the same file as the main routine. See below for more information on how to
// access global variables from code that lives in other source files and gets
// called without going through main.
#if GLOBALS_ALWAYS_AVAILABLE // PowerPC code fragment or 68K application
#define MAIN_SETUP_GLOBALS(x) { x = 0; } // to avoid "unused var" warnings
#define MAIN_RESTORE_GLOBALS(x)
#define TEMP_SETUP_GLOBALS(x) { x = 0; }
#define TEMP_RESTORE_GLOBALS(x)
#elif defined(THINK_C) // Think C A4-based project
#include <SetUpA4.h>
#define MAIN_SETUP_GLOBALS(x) { RememberA0(); SetUpA4(); asm { MOVE.L (A7)+, x } }
#define MAIN_RESTORE_GLOBALS(x) { asm { MOVE.L x, -(A7) } RestoreA4(); }
#define TEMP_SETUP_GLOBALS(x) { SetUpA4(); asm { MOVE.L (A7)+, x } }
#define TEMP_RESTORE_GLOBALS(x) { asm { MOVE.L x, -(A7) } RestoreA4(); }
#elif defined(__MWERKS__) // CodeWarrior A4-based project
#include <A4Stuff.h>
#include <SetUpA4.h>
#define MAIN_SETUP_GLOBALS(x) { x = SetCurrentA4(); RememberA4(); }
#define MAIN_RESTORE_GLOBALS(x) { (void)SetA4(x); }
#define TEMP_SETUP_GLOBALS(x) { x = SetUpA4(); }
#define TEMP_RESTORE_GLOBALS(x) { (void)RestoreA4(x); }
#endif // end of compiler-specific macros
//==============================================================================
// After you set up the environment, all the project globals are available to
// your code no matter what source file it lives in. In some cases, however,
// your code is called without going through the main entry point (callback
// routines, periodic tasks, trap patches and so forth). If this code is in
// the same file as the main routine, you can use TEMP_SETUP_GLOBALS and
// TEMP_RESTORE_GLOBALS; otherwise, you should add a couple of routines to
// your main source file whose only task in life is to set up and restore the
// environment for you. Here's a simple example with two source files that
// shows how to use the macros correctly:
/*
------------------------ FILE: main.c ------------------------
#include "A4Globals.h"
#include "other.h"
// Global variables:
long gNumTimesCalled;
// Main entry point; set up globals, call routines and install callbacks:
pascal OSErr main(void)
{
long world;
MAIN_SETUP_GLOBALS(world);
DoSomethingFromMainFile();
DoSomethingFromOtherFile();
InstallCallbackRoutine(CallbackFromMainFile);
InstallCallbackRoutine(CallbackFromOtherFile);
MAIN_RESTORE_GLOBALS(world);
return noErr;
}
// Called when the globals are already available, no need to set them up again:
void DoSomethingFromMainFile(void)
{
gNumTimesCalled = 0L;
}
// Called without going through main, set up globals with TEMP_SETUP_GLOBALS:
pascal long CallbackFromMainFile(void)
{
long world, timesCalled;
TEMP_SETUP_GLOBALS(world);
++gNumTimesCalled;
timesCalled = gNumTimesCalled;
TEMP_RESTORE_GLOBALS(world);
return timesCalled;
}
// Set up the globals environment for routines that live in other files:
long SetupGlobalsWorld(void)
{
long world;
TEMP_SETUP_GLOBALS(world);
return world;
}
// Restore the globals environment for routines that live in other files:
void RestoreGlobalsWorld(long world)
{
TEMP_RESTORE_GLOBALS(world);
}
------------------------ FILE: other.c ------------------------
#include "main.h"
// Global variables:
extern long gNumTimesCalled;
// Although not in the main file, this is called when the globals are already available:
void DoSomethingFromOtherFile(void)
{
gNumTimesCalled = 0L;
}
// Called without going through main, can't use the macros; call SetupGlobalsWorld instead:
pascal long CallbackFromOtherFile(void)
{
long world, timesCalled;
world = SetupGlobalsWorld();
++gNumTimesCalled;
timesCalled = gNumTimesCalled;
RestoreGlobalsWorld(world);
return timesCalled;
}
*/
//==============================================================================
#endif // _H_a4globals
//==============================================================================